%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<cstring>
#include<unordered_map>
#include<vector>
#ifndef YYSTYPE
#define YYSTYPE double
#endif
using namespace std;
char idStr[50];
vector<double>idtoval;
unordered_map<string,int>nametoid;
//assert: vector.size==nametoid.size
int yylex();
extern int yyparse();
FILE* yyin;
void yyerror(const char *s);
%}
%token ID
%token NUMBER
%token ADD
%token SUB
%token MUL
%token DIV
%token LP
%token RP
%token GET
%left ADD SUB
%left MUL DIV
%right UMINUS
%%
lines   :   lines expr ';' {printf("%f\n",$2);}
        |   lines ';'
        |
        ;

expr    :   expr ADD expr {$$=$1+$3;}
        |   expr SUB expr {$$=$1-$3;}
        |   expr MUL expr {$$=$1*$3;}
        |   expr DIV expr {$$=$1/$3;}
        |   LP expr RP  {$$=$2;}
        |   SUB expr %prec UMINUS   {$$=-$2;}
        |   NUMBER  {$$=$1;}
        |   ID GET expr {$$=$3;idtoval[$1]=$3;}
        |   ID  {$$=idtoval[$1];}
        ;
%%

int yylex(){
    char c;
    while(1){
        c=getchar();
        if(c==' '||c=='\n'||c=='\t');
        else if(isdigit(c))
        {
            yylval=0;
            while(isdigit(c)){
                yylval=yylval*10+c-'0';
                c=getchar();
            }
            ungetc(c,stdin);
            return NUMBER;
        }
        else if(isalpha(c)||c=='_'){
            int idx=0;
            while(isalnum(c)||c=='_'){
                idStr[idx++]=c;
                c=getchar();
            }
            idStr[idx]='\0';
            int nameid=-1;
            string symname(idStr);
            if(nametoid.find(symname)==nametoid.end())
            {
                nameid=idtoval.size();
                idtoval.push_back(0.0);
                nametoid[symname]=nameid;
            }
            else
                nameid=nametoid[symname];
            yylval=nameid;
            ungetc(c,stdin);
            return ID;
        }
        else{
            switch(c)
                {
                    case '+':
                        return ADD;
                    case '-':
                        return SUB;
                    case '*':
                        return MUL;
                    case '/':
                        return DIV;
                    case '(':
                        return LP;
                    case ')':
                        return RP;
                    case '=':
                        return GET;
                    default:
                        return c;
                }
        }
        
    }
}

void yyerror(const char* s){
    fprintf(stderr,"parse error:%s\n",s);
    exit(1);
}
int main(){
    yyin=stdin;
    do{
        yyparse();
    }while(!feof(yyin));
    return 0;
}
